﻿/*
 * Programer: JR Padfield
 * Description:
 * Version: 1
 * Date: 12/17/13 * 
 */

using System;
using TheWorld.Global;
using TheWorld.Components;
using Lidgren.Network;
using TheWorldLibrary.Sprites;
using TheWorldLibrary.Characters;
using TheWorldLibrary.Enumeration;
using Microsoft.Xna.Framework;

namespace TheWorld.Networking
{
    class HandleTCP
    {
        private HandleTCP() { }

        static HandleTCP instance;
        public static HandleTCP Instance
        {
            get
            {
                if (instance == null)
                    instance = new HandleTCP();
                return instance;
            }
        }

        public void HandleData(NetIncomingMessage data)
        {
            // packet header
            int msgType = data.ReadInt32();

            // check packet header number
            if (msgType < 0 && msgType >= (int)ServerPackets.SMSG_COUNT - 1)
                return;

            // handle incoming message
            switch (msgType)
            {
                case (int)ServerPackets.SRegisterOk: HandleRegisterOk(data); break;
                case (int)ServerPackets.SLoginOk: HandleLoginOk(data); break;
                case (int)ServerPackets.SAccountError: HandleAccountError(data); break;
                case (int)ServerPackets.SSendChar: HandleCharacterList(data); break;
                case (int)ServerPackets.SInGame: HandleJoinedGame(data); break;
                case (int)ServerPackets.SAlertMsg: HandleAlertMsg(data); break;
                case(int)ServerPackets.SPlayerMsg: HandlePlayerMsg(data); break;
                case (int)ServerPackets.SMapMsg: HandleMapMsg(data); break;
                case (int)ServerPackets.SPlayerData: HandlePlayerData(data); break;
                case (int)ServerPackets.SPlayerNewXY: HandlePlayerNewXY(data); break;
                case (int)ServerPackets.SLeft: HandleLeftGame(data); break;
                case (int)ServerPackets.SPlayerMove: HandlePlayerMovement(data); break;
            }
        }

        #region Register/Login/Account Creation

        private void HandleRegisterOk(NetIncomingMessage data)
        {
            Static.MyIndex = data.ReadInt32();
            Client.StateManager.ChangeState(Client.CreateCharacterScreen);
        }

        private void HandleLoginOk(NetIncomingMessage data)
        {
            Static.MyIndex = data.ReadInt32();
            Client.StateManager.ChangeState(Client.ChooseCharacterScreen);
        }

        private void HandleAccountError(NetIncomingMessage data)
        {
            Static.menuAlertMessage = data.ReadString();
            General.Instance.AlertMsg(Static.menuAlertMessage, Static.menuAlertColour);
            Console.WriteLine(Static.menuAlertMessage);
        }

        private void HandleCharacterList(NetIncomingMessage data)
        {
            int count = data.ReadInt32();

            for (int i = 0; i < count; i++)
            {
                Client.ChooseCharacterScreen.names[i] = data.ReadString();
                Client.ChooseCharacterScreen.spriteNum[i] = data.ReadInt32();
            }
        }

        private void HandleJoinedGame(NetIncomingMessage data)
        {
            string name = data.ReadString(); ;
            int sprite = data.ReadInt32();
            EntityGender gender = (EntityGender)data.ReadInt32();
            int x = data.ReadInt32();
            int y = data.ReadInt32();
            int mapNum = data.ReadInt32();

            Client.GamePlayScreen.CreatePlayer(name, sprite, gender, new Vector2(x, y), mapNum);

            Client.StateManager.ChangeState(Client.GamePlayScreen);
        }

        #endregion

        #region Player/Movement/Join/Left

        private void HandlePlayerData(NetIncomingMessage data)
        {
            string name = data.ReadString();
            string entityClass = data.ReadString();
            int gender = data.ReadInt32();
            int spriteNum = data.ReadInt32();
            int playerNum = data.ReadInt32();

            if (playerNum == Static.MyIndex)
            {
                return;
            }

            Mapping.Instance.AddCharacter(name, entityClass, gender, spriteNum, playerNum);
        }

        private void HandlePlayerNewXY(NetIncomingMessage data)
        {
            Client.GamePlayScreen.UpdatePlayerXY(data.ReadInt32(), data.ReadInt32());
        }

        private void HandleLeftGame(NetIncomingMessage data)
        {
            Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters.RemoveAt(data.ReadInt32());
        }

        private void HandlePlayerMovement(NetIncomingMessage data)
        {
            // figure out who moved
            int playerIndex = data.ReadInt32();

            if (playerIndex == Static.MyIndex)
            {
                return;
            }

            Player p = new Player();

            AnimationKey key = (AnimationKey)data.ReadInt32();
            float x, y;
            x = data.ReadFloat();
            y = data.ReadFloat();

            // Update player
            //Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Entity.EntityX = data.ReadInt32();
            //Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Entity.EntityY = data.ReadInt32();
            //Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Entity.EntityDir = data.ReadInt32();
            p.UpdatePlayerMovement(key, x, y, playerIndex);
        }

        #endregion

        #region Messages

        private void HandleMapMsg(NetIncomingMessage data)
        {
            string msg = data.ReadString();
            Client.GamePlayScreen.txtRead.AddText(msg);
            Console.WriteLine(msg);
        }

        private void HandlePlayerMsg(NetIncomingMessage data)
        {
            string msg = data.ReadString();
            Client.GamePlayScreen.txtRead.AddText(msg);
            Console.WriteLine(msg);
        }

        private void HandleAlertMsg(NetIncomingMessage data)
        {
            Static.menuAlertMessage = data.ReadString();
            //Static.menuAlertColour = data.ReadInt32();
            General.Instance.AlertMsg(Static.menuAlertMessage, Static.menuAlertColour);
            Console.WriteLine(Static.menuAlertMessage);
        }

        #endregion

        
    }
}
